package ml2;
import org.apache.log4j.BasicConfigurator;


/**
 * These workers take care of calculating the magnification map corresponding
 * a region of the shooting plane.
 * @author pgomez
 *
 */
public class PeriodicDeflector extends AbstractDeflector {

	static{
		BasicConfigurator.configure();
	}

	public PeriodicDeflector(double[][] magnificationMap, double[][] shootingMap, StarBag starBag, 
			double startX, int nx,
			double startY, int ny,
			double sizeX, double sizeY,
			double pixelSize){
		super(magnificationMap, shootingMap, starBag,startX, nx,startY,  ny,sizeX,  sizeY,pixelSize);
	}

	@Override
	public void run() {
		double[] deflected;
		_initialTime = System.currentTimeMillis();


		double x =0;
		double y =0;
		int pixX=0;
		int pixY=0;
		int pixXs=0;
		int pixYs=0;


		for (int j = 0; j < _ny; j++) { //Pixel Y direction
			_currentY= _startY + j*_pixSize + microStep/2;
			for (int i = 0; i < _nx; i++) { //Pixel X direction
				_currentX = _startX + i*_pixSize + microStep/2;
				for (int k = 0; k < DeflectionContext.nRays; k++){ //Sub-Pixel Y direction
					y = _currentY + k*microStep;
					for (int l = 0; l < DeflectionContext.nRays; l++){//Sub-Pixel X direction
						x = _currentX + l*microStep;
						deflected = getDeflected(x, y);

						deflected[0]+=DeflectionContext.sizeMap/2;
						deflected[1]+=DeflectionContext.sizeMap/2;
						if (deflected[0]>0 && deflected[0]<DeflectionContext.sizeMap && 
								deflected[1]>0 && deflected[1]<DeflectionContext.sizeMap){// The ray is in.
							pixX = (int)Math.floor(deflected[0]/_pixSize);
							pixY = (int)Math.floor(deflected[1]/_pixSize);
							pixXs= (int)Math.floor((_currentX + _sizeX/2)/_pixSize);
							pixYs= (int)Math.floor((_currentY + _sizeY/2)/_pixSize);
							_magnificationMap[pixY][pixX]++;
							_shootingMap[pixYs][pixXs]++;
						} else {
							_lostFlux++;
						}
						_totalFlux++;
					}
				}
			}
		}
		_finalTime = System.currentTimeMillis();

	}
	@Override
	public double getProgress(){
		double endX = _startX + _nx*_pixSize;
		double endY = _startY + _ny*_pixSize;
		double xCompletion = (_currentX -_startX)/(endX-_startX);
		return ((_currentY+_pixSize*xCompletion) -_startY)/(endY-_startY);
	}


}
